package org.lestr.secuel.sogl;

import org.lestr.secuel.m3ds.Camera;
import org.lestr.secuel.m3ds.maths.IVecteur3d;

public class SOGLCamera implements Camera {
	
	
	// Déclaration des attributs
	private String nom;
	private double x;
	private double y;
	private double z;
	private double angleX;
	private double angleY;
	private double angleZ;
	
	
	/** Constructeur */
	public SOGLCamera(){
		
		// Instanciation des attributs
		nom = "Nouvelle Caméra";
		x = 0;
		y = 4;
		z = 0;
		angleX = -90;
		angleY = 0;
		angleZ = 0;
		
	}// FIN Constructeur

	
	/** Défini le nom de l'objet */
	public void setNom(String nom){
		
		this.nom = nom;
		
	}// FIN setNom
	
	
	/** Retourne le nom de l'objet */
	public String getNom(){
		
		return nom;
		
	}// FIN obtenirNom

	
	/** Ajoute un écouteur */
	public void ajoutEcouteur(CameraEcouteur écouteur){
		
		// TODO
		
	}// FIN ajoutEcouteur
	
	
	/** Retire un écouteur */
	public void retraitEcouteur(CameraEcouteur écouteur){
		
		// TODO
		
	}// FIN retraitEcouteur
	
	
	/** Positionne selon X */
	public void setX(double x){
		 
		this.x = x;
		
	}// FIN setX
	
	
	/** Retourne X */
	public double getX(){
		
		return x;
		
	}// FIN getX
	
	
	/** Positionne selon Y */
	public void setY(double y){
		
		this.y = y;
		
	}// FIN setY
	
	
	/** Retourne Y */
	public double getY(){
		
		return y;
		
	}// FIN getY
	
	
	/** Positionne selon Z */
	public void setZ(double z){
		
		this.z = z;
		
	}// FIN setZ
	
	
	/** Retourne Z */
	public double getZ(){
		
		return z;
		
	}// FIN getZ
	
	
	/** Positionne selon l'angle X */
	public void setAngleX(double x){
		
		this.angleX = x;
		
	}// FIN setAngleX
	
	
	/** Retourne l'angle X */
	public double getAngleX(){
		
		return angleX;
		
	}// FIN getAngleX
	
	
	/** Positionne selon l'angle Y */
	public void setAngleY(double y){
		
		this.angleY = y;
		
	}// FIN setAngleY
	
	
	/** Retourne l'angle Y */
	public double getAngleY(){
		
		return angleY;
		
	}// FIN getAngleY
	
	
	/** Positionne selon l'angle Z */
	public void setAngleZ(double z){
		
		this.angleZ = z;
		
	}// FIN setAngleZ
	
	
	/** Retourne l'angle Z */
	public double getAngleZ(){
		
		return angleZ;
		
	}// FIN getAngleZ
	
	
	/** Avance la caméra selon sa direction */
	public void avancer(double distance){
		
		x = x + Math.sin(angleY) * distance;
		z = z - Math.cos(angleY) * distance;
		
	}// FIN avancer


	@Override
	public void pointer(double x, double y, double z) {
		
		// Détermine le vecteur séparant la caméra de sa cible 
		IVecteur3d vecteur = Usine.getSingleton().vecteur3D(x - this.x, y - this.y, z - this.z);
		
		// Récupére les vecteurs unitaires et un vecteur temporaire
		IVecteur3d u = Usine.getSingleton().vecteur3D(1,0,0);
		IVecteur3d v = Usine.getSingleton().vecteur3D(0,1,0);
		IVecteur3d w = Usine.getSingleton().vecteur3D(0,0,1);
		IVecteur3d tmp = null;
		
		// Projete le vecteur dans le plan (v,w)
		tmp = Usine.getSingleton().vecteur3D();
		IVecteur3d projetéDansPlanX = Usine.getSingleton().vecteur3D();
		tmp.produitCartésien(u, vecteur);
		projetéDansPlanX.produitCartésien(u, tmp);
		
		angleX = -w.obtenirAngle(projetéDansPlanX);
		u = projetéDansPlanX;
		
		// Projete le vecteur dans le plan (u,w)
		tmp = Usine.getSingleton().vecteur3D();
		IVecteur3d projetéDansPlanY = Usine.getSingleton().vecteur3D();
		tmp.produitCartésien(v, vecteur);
		projetéDansPlanY.produitCartésien(v, tmp);
		
		angleY = -u.obtenirAngle(projetéDansPlanY)+90;
		v = projetéDansPlanY;
		
		// Projete le vecteur dans le plan (u,v)
		tmp = Usine.getSingleton().vecteur3D();
		IVecteur3d projetéDansPlanZ = Usine.getSingleton().vecteur3D();
		tmp.produitCartésien(w, vecteur);
		projetéDansPlanZ.produitCartésien(w, tmp);
		
		
		angleZ = v.obtenirAngle(projetéDansPlanZ)-90;

		System.out.println(angleX + " " + angleY + " " + angleZ);
		//System.out.println(vecteur.getX() + " " + vecteur.getY() + " " + vecteur.getZ());
		
	}// FIN pointer
	

}// FIN Classe
